package com.service.impl;

import com.dao.GoodsForOrderinfoDao;
import com.dao.OrderdetailForOrderinfoDao;
import com.dao.OrderinfoDao;
import com.dao.RedisDao;
import com.dto.BaseDto;
import com.dto.MessageEnum;
import com.entity.Goods;
import com.entity.Orderdetail;
import com.entity.Orderinfo;
import com.fasterxml.jackson.annotation.JacksonAnnotationValue;
import com.page.PageInfo;
import com.service.OrderinfoService;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Service
public class OrderinfoServiceImpl implements OrderinfoService {
    @Resource
    OrderinfoDao orderinfoDao;
    @Resource
    GoodsForOrderinfoDao goodsForOrderinfoDao;
    @Resource
    HttpServletResponse response;
    @Resource
    HttpServletRequest request;
    @Resource
    RedisDao redisDao;

    @Resource
    OrderdetailForOrderinfoDao orderdetailForOrderinfoDao;
    public Orderinfo getByOrid(String orid){
      return orderinfoDao.getByOrid(orid);
    }
    //业务逻辑层，根据业务逻辑确定返回给页面的消息和状态以及对象
    public BaseDto<Orderinfo> getAll(){
        List<Orderinfo> orderinfos = orderinfoDao.getAll();
        //通过判断dao层返回的对象的集合大小来说明本次查询是成功还是失败 如果大于0成功有返回的结果集，否则就没有查到东西就是失败
        MessageEnum messageEnum = orderinfos.size() > 0?MessageEnum.SELECT_ADMINBYPAGE_SUCCESS:MessageEnum.SELECT_ADMINBYPAGE_FAIL;
        BaseDto<Orderinfo> dto = new BaseDto<>(messageEnum,orderinfos);
        return dto;
    }

    public BaseDto<Orderinfo> getAllByPage(PageInfo pageInfo){
        List<Orderinfo> orderinfos = orderinfoDao.getAllByPage(pageInfo);
        //通过判断dao层返回的对象的集合大小来说明本次查询是成功还是失败 如果大于0成功有返回的结果集，否则就没有查到东西就是失败
        MessageEnum messageEnum = orderinfos.size() > 0?MessageEnum.SELECT_ADMINBYPAGE_SUCCESS:MessageEnum.SELECT_ADMINBYPAGE_FAIL;
        BaseDto<Orderinfo> dto = new BaseDto<>(messageEnum,orderinfos);
        dto.setObj(pageInfo);
        return dto;
    }


    public BaseDto<Orderinfo> searchNameByPage(PageInfo pageInfo,String adname){
        List<Orderinfo> orderinfos = orderinfoDao.searchNameByPage(pageInfo,"%"+adname+"%");
        //通过判断dao层返回的对象的集合大小来说明本次查询是成功还是失败 如果大于0成功有返回的结果集，否则就没有查到东西就是失败
        MessageEnum messageEnum = orderinfos.size() > 0?MessageEnum.SEARCHADMIN_SUCCESS:MessageEnum.SEARCHADMIN_FAIL;
        BaseDto<Orderinfo> dto = new BaseDto<>(messageEnum,orderinfos);
        dto.setObj(pageInfo);
        return dto;
    }

    /**
     * 根据主键查询
     * @param orid
     * @return
     */
    public BaseDto getOrderinfoByOrid(String orid){
        Orderinfo orderinfo = orderinfoDao.getOrderinfoByOrid(orid);
        MessageEnum messageEnum = Optional.ofNullable(orderinfo).isPresent()?MessageEnum.SELECT_ADMINBYPK_SUCCESS:MessageEnum.SELECT_ADMINBYPK_FAIL;
        BaseDto dto = new BaseDto(messageEnum);
        dto.setT(orderinfo);
        return dto;
    }

    /**
     * 添加一个实体
     * @param orderinfo
     * @return
     */
    public BaseDto addOrderinfo(Orderinfo orderinfo){
        int result = orderinfoDao.addOrderinfo(orderinfo);
        MessageEnum messageEnum = result>0?MessageEnum.ADDADMIN_SUCCESS:MessageEnum.ADDADMIN_FAIL;
        BaseDto dto = new BaseDto(messageEnum);
        dto.setT(orderinfo);
        return dto;
    }
    /**
     * 修改实体
     */
    public BaseDto updateOrderinfo(Orderinfo orderinfo){
        int result = orderinfoDao.updateOrderinfo(orderinfo);
        MessageEnum messageEnum = result>0?MessageEnum.UPDATEADMINBYPK_SUCCESS:MessageEnum.UPDATEADMINBYPK_FAIL;
        BaseDto dto = new BaseDto(messageEnum);
        dto.setT(orderinfo);
        return dto;
    }
    public BaseDto updateOrderinfoByExample(){
        return null;
    }

    /**
     * 删除一个实体
     * @param orid
     * @return
     */
    public BaseDto deleteOrderinfoByPrimayKey(String orid){
        int result = orderinfoDao.deleteOrderinfoByPrimayKey(orid);
        MessageEnum messageEnum = result>0?MessageEnum.DELETEADMINBYPK_SUCCESS:MessageEnum.DELETEADMINBYPK_FAIL;
        BaseDto dto = new BaseDto(messageEnum);
        return dto;
    }

    /**
     * 删除实体根据示例
     * @return
     */
    public BaseDto<Goods> deleteOrderinfoByExample(){
        return null;
    }

    /**
     * 传入购物车中的商品编号数组得到最新的购物车中的商品集合并保存cookie
     * @param gidsList 商品编号集合
     * @return  dto 包含了 保存购物车的状态
     */
    public  BaseDto<Goods> getByGtids(List<String> gidsList){
        String gids = "";//将数组转换成 in 语句需要的  表达式
        for(String gid : gidsList){
           gids += "'" + gid + "',";
        }
        gids = gids.substring(0,gids.length() - 1);//去掉最后一个逗号
        List<Goods> goodss = goodsForOrderinfoDao.getByGtids(gids);
        MessageEnum messageEnum = goodss.size() > 0?MessageEnum.SAVE_GOODSCAR_SUCCESS:MessageEnum.SAVE_GOODSCAR_FAIL;
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        String cookieVal = new String(jackson2JsonRedisSerializer.serialize(goodss));//将查询出的集合对象序列化成字节数组后组成字符串提供给cookie

        Cookie cookieGoodsCar = new Cookie("userGoodsCar",cookieVal);
        cookieGoodsCar.setHttpOnly(true);
        cookieGoodsCar.setMaxAge(7*24*3600);
        response.addCookie(cookieGoodsCar);



        BaseDto<Goods> dto = new BaseDto<>(messageEnum,goodss);
        return dto;
    }

    /**
     * 将购物车的中的商品形成订单 保存到redis
     * @param gidsList 商品编号集合
     * @return  dto 包含了 保存购物车的状态
     */
    public  BaseDto addOrderinfoByGtids(List<String> gidsList){
        String gids = "";//将数组转换成 in 语句需要的  表达式
        for(String gid : gidsList){
            gids += "'" + gid + "',";
        }
        gids = gids.substring(0,gids.length() - 1);//去掉最后一个逗号
        List<Goods> goodss = goodsForOrderinfoDao.getByGtids(gids);
        MessageEnum messageEnum = goodss.size() > 0?MessageEnum.SAVE_GOODSCAR_SUCCESS:MessageEnum.SAVE_GOODSCAR_FAIL;
        Orderinfo orderinfo = new Orderinfo();
        orderinfo.setOrtime(new Date());//设置订单时间
        orderinfo.setBuid((String)request.getSession().getAttribute("buid"));
        //订单编号
        String orUuid = UUID.randomUUID().toString();	//获取UUID并转化为String对象
        orUuid = orUuid.replace("-", "");				//因为UUID本身为32位只是生成时多了“-”，所以将它们去点就可
        //System.out.println(uuid);
        orderinfo.setOrid(orUuid);

        List<Orderdetail> orderdetails = new ArrayList<Orderdetail>();
        for(Goods goods :goodss){
            //订单详情编号
            String odUuid = UUID.randomUUID().toString();	//获取UUID并转化为String对象
            odUuid = odUuid.replace("-", "");
            Orderdetail od = new Orderdetail();
            od.setOdid(odUuid);
            od.setGid(goods.getGid());//将商品编号保存到订单详情
            od.setGnum(goods.getGnum());//将商品数量保存到订单详情
            od.setGrealprice(goods.getGprice());//将商品价格保存到订单详情
            orderdetails.add(od);
        }

        orderinfo.setOrderdetails(orderdetails);
        redisDao.pushObj(orderinfo,orderinfo.getBuid()+"_"+orderinfo.getOrid());//存放订单到redis


        BaseDto dto = new BaseDto<>(messageEnum,goodss);
        return dto;
    }





    /**
     * 从cookie中读取 是否存了购物车，返回存的dto包含购物车
     *
     * @return  dto 包含了 保存购物车的状态
     */
    public  BaseDto<Goods> initGoodsCarFromCookie(){
        Cookie[] cookies = request.getCookies();
        BaseDto<Goods> dto  = null;
        if(!Optional.ofNullable(cookies).isPresent()){
     dto = new BaseDto<>(4001,"没有cookie");
        }else {
            List<Goods> goodss = null;
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("userGoodsCar")) {
                    GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

                    goodss = (List<Goods>) jackson2JsonRedisSerializer.deserialize(cookie.getValue().getBytes());
                    break;
                }

            }
            MessageEnum messageEnum = goodss.size() > 0 ? MessageEnum.SAVE_GOODSCAR_SUCCESS : MessageEnum.SAVE_GOODSCAR_FAIL;
            dto = new BaseDto<>(messageEnum, goodss);
        }
        return dto;

    }

    /**
     * 根据订单号 完成支付，删除redis中的key ，保存订单和订单详情到数据库
     * @param orid
     * @return
     */
    public  BaseDto pay(String orid){
        //将已支付的订单从redis中移除，将取出的数据，保存到mysql
        String keyStr = request.getSession().getAttribute("buid")+"_"+orid;
        Orderinfo orderinfo = (Orderinfo) redisDao.getObj(request.getSession().getAttribute("buid")+"_"+orid);
       redisDao.delete(keyStr);

       int result = orderinfoDao.addOrderinfo(orderinfo);
       for(Orderdetail orderdetail :orderinfo.getOrderdetails()) {
           orderdetailForOrderinfoDao.addOrderdetail(orderdetail);
       }
       MessageEnum messageEnum = result > 0?MessageEnum.SELECT_ADMINBYPAGE_SUCCESS:MessageEnum.SELECT_ADMINBYPAGE_FAIL;
       return new BaseDto(messageEnum);
    }

}
